#!/bin/sh
#
# execute this to create an "irclink" executable in the current
# directory for your UNIX system.
#
# defaults to "cc", change this if you must :-)
ccomp=cc
# Remove -s if you do not want to strip the binary
cflags=-s

cat > irclink-out.c << 'EOFIRCLINK'
/*
 * irclink.c  -- UNIX-side serial support for Grapevine
 *  	
 * define CF_SGTTY for sgtty systems
 */

#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#ifdef AIX
#include <sys/select.h>
#endif
#ifdef CF_SGTTY
#include <sgtty.h>
#else
#include <termios.h>
#endif
#include <stdio.h>
#include <fcntl.h>
#include <signal.h>

#ifndef INADDR_NONE
#define INADDR_NONE -1
#endif

#define BUFSIZE 32

#ifdef CF_SGTTY
#ifndef FREAD
#define FREAD 0x0001
#endif
#ifndef FWRITE
#define FWRITE 0x0002
#endif
struct sgttyb  ostty,    nstty;
struct tchars  otchars,  ntchars;
struct ltchars oltchars, nltchars;
int            olmode,   nlmode;      
int            inout = FREAD|FWRITE;  
#else
struct termios temp_tios;
#endif

int temp;

int CleanUp( i )
int i;
{
	if( temp )
		{
#ifdef CF_SGTTY
		(void)ioctl(0, (int)TIOCFLUSH, (char *)&inout);
        (void)ioctl(0, (int)TIOCSETP, (char *)&ostty);
        (void)ioctl(0, (int)TIOCSETC, (char *)&otchars);
        (void)ioctl(0, (int)TIOCSLTC, (char *)&oltchars);
        (void)ioctl(0, (int)TIOCLSET, (char *)&olmode);
#else
		tcsetattr( 0, TCSANOW, &temp_tios );
#endif
		}
	fcntl( 0, F_SETFL, fcntl( 0, F_GETFL, 0 ) & ~O_NDELAY );
	exit( 0 );
}

int HandleIO( fd )   /* Shuffle data between fd and stdin/stdout */
int fd;
{
	int result, i;
	char inbuf[BUFSIZE];
	struct fd_set rd;
	struct fd_set zer;
#ifndef CF_SGTTY
	struct termios tios;
#endif
	struct timeval timeout;

	signal( SIGINT,  (void *) CleanUp );	/* Clean up sockets when killed */
	signal( SIGTSTP, (void *) CleanUp );
	signal( SIGSEGV, (void *) CleanUp );
	signal( SIGBUS,  (void *) CleanUp );
	signal( SIGQUIT, (void *) CleanUp );
	signal( SIGKILL, (void *) CleanUp );

#ifdef CF_SGTTY
        ioctl(0, (int)TIOCGETP, (char *)&ostty);
        ioctl(0, (int)TIOCGETC, (char *)&otchars);
        ioctl(0, (int)TIOCGLTC, (char *)&oltchars);
        ioctl(0, (int)TIOCLGET, (char *)&olmode);
        nstty              = ostty;
        ntchars            = otchars; 
        nltchars           = oltchars;
        nlmode             = olmode;  


        nstty.sg_flags  = RAW;     /* | = RAW;  nstty.sg_flags &= ~ECHO; */

        nstty.sg_erase     = nstty.sg_kill     = -1;

        ntchars.t_intrc    = ntchars.t_quitc   = -1;
        ntchars.t_eofc     = ntchars.t_brkc    = -1;

        nltchars.t_suspc   = nltchars.t_dsuspc = -1;
      nltchars.t_rprntc  = nltchars.t_flushc = -1;
        nltchars.t_werasc  = nltchars.t_lnextc = -1;

        /* tell ourselves about it */ 
        ioctl(0, (int)TIOCSETN, (char *)&nstty);
        ioctl(0, (int)TIOCSETC, (char *)&ntchars);
        ioctl(0, (int)TIOCSLTC, (char *)&nltchars);
        ioctl(0, (int)TIOCLSET, (char *)&nlmode);
#else
	tcgetattr( 0, &tios );		/* Get attributes for stdin				*/
	temp_tios = tios;			/* Make copy of tios for restoration	*/
	temp =1;
	tios.c_lflag &= ~ICANON;	/* Disable canonical input              */
	tios.c_cc[VMIN] = 1;		/* Read at least 1 character			*/
	tios.c_cc[VTIME] = 0;		/* Disable timeout						*/
	tios.c_lflag &= ~ECHO;		/* No echo								*/
	tios.c_lflag &= ~ISIG;		/* Disable input signals				*/
	tios.c_cflag &= ~CSIZE;
	tios.c_cflag |=  CS8;		/* 8 bit connection						*/
	tios.c_cflag &= ~PARENB;	/* No output parity						*/
	tios.c_iflag &= ~INPCK;		/* No input parity						*/
	tios.c_iflag &= ~ISTRIP;	/* Do not strip 8th bit					*/
	tios.c_iflag &= ~IXON;		/* Disable XON/XOFF						*/
	tios.c_iflag &= ~IXOFF;
	tios.c_iflag &= ~INLCR;		/* No NL -> CR remapping				*/
	tios.c_iflag &= ~ICRNL;		/* No NL -> CR remapping				*/
	tios.c_oflag &= ~OPOST;		/* Disable output post processing		*/

	tcsetattr( 0, TCSANOW, &tios );

	timeout.tv_sec = 1;
	timeout.tv_usec = 0;
#endif

	fcntl( 0, F_SETFL, O_NDELAY );	/* Disable read blocking */
	fcntl( fd, F_SETFL, O_NDELAY );
	while( 1 )
	{
		FD_ZERO( &rd );
		FD_SET( 0, &rd );	/* Determine whether 0 can be read	*/
		FD_SET( fd, &rd );	/* Determine whether fd can be read	*/
		FD_ZERO( &zer );	/* No write or exception queries	*/

		if( select( NFDBITS, &rd, &zer, &zer, &timeout ) != -1 )
		{
			if( FD_ISSET( 0, &rd ) )
			{  /* read zero */
				result = read( 0, inbuf, BUFSIZE );
				if( result > 0 )
				{
					write( fd, inbuf, result );
				}
				if( result < 0 )
				{
					printf( "\n\nEOF detected, exiting.\n" );
					CleanUp( 0 );
				}
			}
			if( FD_ISSET( fd, &rd ) )
			{
				result = read( fd, inbuf, BUFSIZE );
				if( result > 0 )
					write( 1, inbuf, result );
				if( result < 0 )
				{
					printf( "\n\nERROR: Connection to server lost, quitting.\n" );
					CleanUp(0);
				}
			}
		}
	}
}

int ConnectToServer( servername, port )
char *servername;
int port;
{
	int sock;
	struct hostent *host;
	struct sockaddr_in serv;

	printf( "Connecting to server %s port %ld.\n", servername, port );

	sock = socket( AF_INET,SOCK_STREAM,0 );
	if( sock < 0 )
	{
		fprintf( stderr, "irclink: Could not get socket.\n" );
		return( -1 );
	}

	serv.sin_addr.s_addr = inet_addr( servername );
	serv.sin_port = htons( port );
	serv.sin_family = AF_INET;

	if( serv.sin_addr.s_addr == INADDR_NONE )
	{
		if( host = (struct hostent *) gethostbyname( servername ) )
		{
			memcpy( &serv.sin_addr, host->h_addr, host->h_length );
		}
		else
		{
			fprintf( stderr, "irclink: Unknown host.\n" );
			return( -1 );
		}
	}

	if( connect( sock, (struct sockaddr *)&serv, sizeof( struct sockaddr_in ) ) == -1)
		return( -1 );
	else
		return( sock );
}

main( argc, argv )
int argc;
char **argv;
{
	char buf[2];
	char *cmdarg;
	char *servername;
	int sock;
	int port;
	port = 6667;

	temp = 0;

	if( argv[1] )
		servername = argv[1];
	else
	{
		printf( "Usage 2: %s server [port]\n", argv[0] );
		exit( 1 );
	}

	if( argv[2] )
		port = atoi( argv[2] );

	sock = ConnectToServer( servername, port );

	if( sock < 0 )
	{
		fprintf( stderr, "irclink: Could not connect to server.\n" );
		exit( 5 );
	}

	printf( "Connected to server %s.\n", servername );
	HandleIO( sock );
	CleanUp( 0 );    /* make sure to clean up */
	return( 0 );
}
EOFIRCLINK

if [ -f /usr/include/termios.h ] ; then
	if [ -f /usr/include/sys/aixgsc.h ] ; then           
		$ccomp -DAIX -o irclink irclink-out.c $cflags
	else                                                 
		$ccomp -o irclink irclink-out.c $cflags      
	fi
else
	$ccomp -DCF_SGTTY -o irclink irclink-out.c $cflags
fi
rm irclink-out.c
